

const API_BASE_URL = 'http://localhost:8080'; // 后端接口地址
let socket; // WebSocket 连接
let currentConversation = null; // 当前选中的会话

const token = localStorage.getItem("token"); // 从 localStorage 获取 token
const WS_URL = localStorage.getItem("gateUrl"); // 从 localStorage 获取 token

const userId = localStorage.getItem("userId");

let nick = "";
let avatar = "";

let currentPage = 1; // 当前页码
const pageSize = 10; // 每页数据量
let isLoading = false; // 是否正在加载数据

var qosQueue = []; // 存储需要确认的消息 ID
var isQosRunning = false; // 标记是否正在发送批量 QoS

function sendBatchQos() {
    if (isQosRunning || qosQueue.length === 0) {
        return;
    }
    isQosRunning = true;

    // 按会话类型分组
    let groupedQos = {};
    qosQueue.forEach(item => {
        if (!groupedQos[item.converType]) {
            groupedQos[item.converType] = [];
        }
        groupedQos[item.converType].push(item.msgId);
    });

    // 发送每组 QoS
    Object.keys(groupedQos).forEach(converType => {
        let msgIds = groupedQos[converType];

        let qosData = {
            senderId: userId,
            receiverId: "0",
            msgIds: msgIds,
            converType: converType
        };

        console.log("发送批量 QoS:", qosData);
        socket.send(createCustomMessage(199, 1, 1, 10, JSON.stringify(qosData)));
    });

    // 清空队列
    qosQueue = [];
    isQosRunning = false;
}

function getUserInfo() {
    fetch(`${API_BASE_URL}/web/user/info?userId=${userId}`, {
        headers: {
            "clientid": "fdsdfdf2323hfdgk5645",
            "Authorization": `Bearer ${token}`, // 添加 Authorization 请求头
            "Content-Type": "application/json", // 可选，根据后端需求添加
        },
    })
        .then(response => {
            if (!response.ok) {
                throw new Error(`请求失败，状态码：${response.status}`);
            }
            return response.json();
        })
        .then(data => {
            if (data.code === 200) {
                nick = data.data.nick;
                avatar = data.data.avatar;
                console.log("nick=", nick);
                // 更新左侧头像
                document.querySelector('.left-panel .avatar').src = avatar;
            } else {
                console.error("获取用户信息出错：", data.msg);
            }
        })
        .catch(error => {
            console.error("请求出错：", error);
        });
}

// 初始化页面
window.onload = function () {
    getUserInfo();
    connectWebSocket(); // 自动连接 WebSocket
    fetchConversations(); // 获取第一页会话列表
    setupScrollListener(); // 设置滚动监听
};

// 连接 WebSocket
function connectWebSocket() {
    const wsUrl = WS_URL || "ws://localhost:30000/ws";
    socket = new WebSocket(wsUrl);

    socket.onopen = function () {
        console.log("WebSocket 连接成功");
        socket.binaryType = "arraybuffer";

        logout(`${userId}`, "windows", "test");
        login(`${userId}`, "windows", "test");
        setInterval(sendBatchQos, 1000);
    };

    socket.onmessage = function (event) {
        const receivedObject = parseBinaryDataToObject(event);
        console.log("收到消息:", receivedObject);

        if (receivedObject.cmd === 1001) { // 登录成功
            console.log("开始发送心跳");
            heartBeat();
        }
        if (receivedObject.cmd === 1002) { // pong
            heartBeat();
        }
        if (receivedObject.cmd === 1003) {
            let dataStr = JSON.parse(receivedObject.data);
            let message = JSON.parse(dataStr);
            console.log("------------------02222222222222222222222222222", message);
            // 接收者
            if (userId != message.senderId) {
                // qos
                qosQueue.push({
                    msgId: message.id,
                    converType: message.conversationType
                });
                console.log("单聊消息添加到 QoS 队列:", message.id);
            }
        }
        if (receivedObject.cmd === 1005) {
            let dataStr = JSON.parse(receivedObject.data);
            let message = JSON.parse(dataStr.data);
            console.log("------------------vvvv", message);
            // 接收者
            if (userId != message.senderId) {
                // qos
                qosQueue.push({
                    msgId: message.id,
                    converType: message.conversationType
                });
                console.log("群聊消息添加到 QoS 队列:", message.id);
            }
        }

        // 处理消息逻辑
        handleReceivedMessage(receivedObject);
    };

    socket.onclose = function () {
        console.log("WebSocket 连接关闭");
    };
}

function logout(userId, systemOs, appKey) {
    var cmd = 200;
    var version = 1;
    var serial = 10;
    var encrypt = 1;

    var data = {
        "userId": userId,
        "appKey": appKey,
        "deviceType": 13,
        "currTime": new Date().getTime()
    };
    var jsonData = JSON.stringify(data);
    console.log(jsonData);
    socket.send(createCustomMessage(cmd, version, encrypt, serial, jsonData));
}

function login(userId, systemOs, appKey) {
    if (!window.WebSocket) {
        return;
    }
    console.log(userId);
    // 当websocket状态打开
    if (socket.readyState == WebSocket.OPEN) {
        var cmd = 1;
        var version = 1;
        var serial = 10;
        var encrypt = 1;

        var data = {
            "userId": userId,
            "appKey": appKey,
            "systemOs": systemOs,
            "deviceType": 13,
            "token": null,
            "currTime": new Date().getTime()
        };
        var jsonData = JSON.stringify(data);
        console.log(jsonData);
        socket.send(createCustomMessage(cmd, version, encrypt, serial, jsonData));
    } else {
        alert("连接没有开启");
    }
}

// 获取会话列表
function fetchConversations(pageNum = 1) {
    if (isLoading) return; // 如果正在加载数据，直接返回
    isLoading = true; // 标记为正在加载

    const token = localStorage.getItem("token"); // 从 localStorage 获取 token
    if (!token) {
        console.error("未找到 token，请先登录");
        return;
    }

    fetch(`${API_BASE_URL}/web/conver/list?pageNum=${pageNum}&pageSize=${pageSize}`, {
        headers: {
            "clientid": "fdsdfdf2323hfdgk5645",
            "Authorization": `Bearer ${token}`, // 添加 Authorization 请求头
            "Content-Type": "application/json", // 可选，根据后端需求添加
        },
    })
        .then(response => {
            if (!response.ok) {
                throw new Error(`请求失败，状态码：${response.status}`);
            }
            return response.json();
        })
        .then(data => {
            if (data.code === 200) {
                if (pageNum === 1) {
                    // 如果是第一页，直接渲染
                    renderConversationList(data.rows);
                } else {
                    // 如果是后续页，追加数据
                    appendConversationList(data.rows);
                }
                currentPage = pageNum; // 更新当前页码
            } else {
                console.error("获取会话列表失败：", data.msg);
            }
        })
        .catch(error => {
            console.error("请求出错：", error);
        })
        .finally(() => {
            isLoading = false; // 标记为加载完成
        });
}

// 渲染会话列表
function renderConversationList(conversations) {
    const conversationList = document.getElementById("conversationList");
    conversationList.innerHTML = ""; // 清空列表
    appendConversationList(conversations); // 追加数据
}

// 追加会话列表
function appendConversationList(conversations) {
    const conversationList = document.getElementById("conversationList");

    conversations.forEach(conversation => {
        const li = document.createElement("li");
        li.className = "conversation-item";

        // 头像
        const avatarUrl = conversation.targetUser?.avatarUrl || conversation.group?.groupAvatar || "https://via.placeholder.com/40";
        const avatar = document.createElement("img");
        avatar.src = avatarUrl;
        avatar.className = "avatar";
        li.appendChild(avatar);

        // 内容区域
        const content = document.createElement("div");
        content.className = "content";

        // 昵称
        const nickname = document.createElement("div");
        nickname.className = "nickname";
        nickname.textContent = conversation.targetUser?.nickname || conversation.group?.name || `会话 ${conversation.targetId}`;
        content.appendChild(nickname);

        // 最新消息
        const latestMessage = document.createElement("div");
        latestMessage.className = "latest-message";

        // 提取 payload 中的 text 内容
        let messageText = "暂无消息";
        if (conversation.message?.payload) {
            try {
                const payload = JSON.parse(conversation.message.payload);
                messageText = payload.text || "暂无消息";
            } catch (e) {
                console.error("解析 payload 失败：", e);
                messageText = conversation.message.payload; // 如果解析失败，直接显示原始内容
            }
        }
        latestMessage.textContent = messageText;
        content.appendChild(latestMessage);

        li.appendChild(content);

        // 时间
        const time = document.createElement("div");
        time.className = "time";
        time.textContent = formatTime(conversation.message?.sendTime);
        li.appendChild(time);

        li.addEventListener("click", () => selectConversation(conversation));
        conversationList.appendChild(li);
    });
}

// 格式化时间
function formatTime(timestamp) {
    if (!timestamp) return "";
    const date = new Date(timestamp);
    return `${date.getHours()}:${String(date.getMinutes()).padStart(2, "0")}`;
}

// 监听滚动事件
function setupScrollListener() {
    const conversationList = document.getElementById("conversationList");
    conversationList.addEventListener("scroll", () => {
        const {scrollTop, scrollHeight, clientHeight} = conversationList;
        if (scrollTop + clientHeight >= scrollHeight - 10 && !isLoading) {
            // 滚动到底部，加载下一页
            fetchConversations(currentPage + 1);
        }
    });
}

// 选择会话
function selectConversation(conversation) {
    currentConversation = conversation;
    document.getElementById("chatHeader").innerHTML = `
            <img src="${conversation.targetUser?.avatarUrl || conversation.group?.groupAvatar || "https://via.placeholder.com/40"}" alt="头像" class="avatar">
            <span>${conversation.targetUser?.nickname || conversation.group?.name || `会话 ${conversation.targetId}`}</span>
        `;
    fetchMessages(conversation.targetId); // 获取会话消息
}

// 获取会话消息
function fetchMessages(targetId) {
    fetch(`${API_BASE_URL}/getMessages?targetId=${targetId}`)
        .then(response => response.json())
        .then(data => {
            if (data.code === 200) {
                renderMessages(data.data);
            }
        });
}

// 渲染聊天消息
function renderMessages(messages) {
    const chatMessages = document.getElementById("chatMessages");
    chatMessages.innerHTML = ""; // 清空消息

    messages.forEach(message => {
        const div = document.createElement("div");
        div.className = `message ${message.senderId === `${userId}` ? "self" : ""}`;

        // 头像
        const avatar = document.createElement("img");
        avatar.src = message.senderId === `${userId}` ? avatar : (currentConversation.targetUser?.avatarUrl || currentConversation.group?.groupAvatar || "https://via.placeholder.com/40");
        avatar.className = "avatar";
        div.appendChild(avatar);

        // 消息内容
        const content = document.createElement("div");
        content.className = "content";

        // 提取 payload 中的 text 内容
        let messageText = message.payload;
        if (message.payload) {
            try {
                const payload = JSON.parse(message.payload);
                messageText = payload.text || message.payload;
            } catch (e) {
                console.error("解析 payload 失败：", e);
                messageText = message.payload; // 如果解析失败，直接显示原始内容
            }
        }
        content.textContent = messageText;
        div.appendChild(content);

        chatMessages.appendChild(div);
    });

    // 滚动到底部
    chatMessages.scrollTop = chatMessages.scrollHeight;
}

// 发送消息
function sendMessage() {
    const messageInput = document.getElementById("messageInput");
    const message = messageInput.value.trim();

    if (message && currentConversation) {
        let converType = 'c2c';
        if (currentConversation.converType === 2) {
            converType = 'c2g';
        }
        const messageData = {
            senderId: `${userId}`,
            receiverId: currentConversation.targetId,
            payload: JSON.stringify({text: message}), // 确保 payload 包含 {text: ""}
            conversationType: converType,
            type: 1,
            flow: 'up',
            clientMsgId: uuid(),
            time: new Date().getTime()
        };
        console.log("发送消息：", messageData);
        socket.send(createCustomMessage(3, 1, 1, 10, JSON.stringify(messageData)));

        // 手动将消息添加到聊天框中
        const chatMessages = document.getElementById("chatMessages");
        const div = document.createElement("div");
        div.className = "message self"; // 自己发送的消息

        // 头像
        const avatarImg = document.createElement("img");
        avatarImg.src = avatar;
        avatarImg.className = "avatar";
        div.appendChild(avatarImg);

        // 消息内容
        const content = document.createElement("div");
        content.className = "content";
        content.textContent = message;
        div.appendChild(content);

        chatMessages.appendChild(div);

        // 滚动到底部
        chatMessages.scrollTop = chatMessages.scrollHeight;

        messageInput.value = ""; // 清空输入框
    }
}

// 处理收到的消息
function handleReceivedMessage(message) {
    if (message.cmd === 1003 || message.cmd === 1005) { // 单聊或群聊消息
        const chatMessages = document.getElementById("chatMessages");
        const div = document.createElement("div");
        div.className = `message ${message.senderId === `${userId}` ? "self" : ""}`;

        // 头像
        const avatarImg = document.createElement("img");
        avatarImg.src = message.senderId === `${userId}` ? avatar : (currentConversation.targetUser?.avatarUrl || currentConversation.group?.groupAvatar || "https://via.placeholder.com/40");
        avatarImg.className = "avatar";
        div.appendChild(avatarImg);

        // 消息内容
        const content = document.createElement("div");
        content.className = "content";

        // 提取 payload 中的 text 内容
        let messageText = message.payload;
        if (message.payload) {
            try {
                const payload = JSON.parse(message.payload);
                messageText = payload.text || message.payload;
            } catch (e) {
                console.error("解析 payload 失败：", e);
                messageText = message.payload; // 如果解析失败，直接显示原始内容
            }
        }
        content.textContent = messageText;
        div.appendChild(content);

        chatMessages.appendChild(div);

        // 滚动到底部
        chatMessages.scrollTop = chatMessages.scrollHeight;
    }
}

// 其他函数（createCustomMessage、parseBinaryDataToObject 等）保持不变
// 定义 createCustomMessage 函数
function createCustomMessage(cmd, version, encrypt, serial, dataStr) {
    // 魔术值固定为8
    const magic = 8;

    // 假设所有字节数据都在0-255之间

    // 创建魔术值视图
    const magicView = new DataView(new ArrayBuffer(1));
    magicView.setUint8(0, magic);

    // 创建cmd视图，现在它是4个字节
    const cmdView = new DataView(new ArrayBuffer(4));
    cmdView.setUint32(0, cmd, false); // 注意endianness（这里是大端序）

    const versionView = new DataView(new ArrayBuffer(1));
    versionView.setUint8(0, version);

    const encryptView = new DataView(new ArrayBuffer(1));
    encryptView.setUint8(0, encrypt);

    const serialView = new DataView(new ArrayBuffer(1));
    serialView.setUint8(0, serial);

    // 将字符串转换为UTF-8编码的ArrayBuffer
    let encoder = new TextEncoder();
    let dataView = encoder.encode(dataStr);

    // 计算并添加4字节的长度字段
    let dataLength = dataView.byteLength;
    console.log("datalenght=", dataLength);
    const lengthView = new DataView(new ArrayBuffer(4));
    lengthView.setUint32(0, dataLength, false); // 注意endianness（这里是大端序）

    // 合并所有的ArrayBuffer
    let totalLength = 1 + 4 + 1 + 1 + 1 + 4 + dataView.byteLength;
    let combinedBuffer = new ArrayBuffer(totalLength);
    let combinedView = new DataView(combinedBuffer);

    // 复制每个部分到combinedBuffer中
    let offset = 0;

    // 首先复制魔术值
    combinedView.setUint8(offset++, magicView.getUint8(0));

    // 然后复制cmd字段
    for (let i = 0; i < 4; i++) {
        combinedView.setUint8(offset++, cmdView.getUint8(i));
    }

    combinedView.setUint8(offset++, versionView.getUint8(0));
    combinedView.setUint8(offset++, encryptView.getUint8(0));
    combinedView.setUint8(offset++, serialView.getUint8(0));

    // 复制长度字段
    for (let i = 0; i < 4; i++) {
        combinedView.setUint8(offset++, lengthView.getUint8(i));
    }

    // 最后复制数据
    for (let i = 0; i < dataView.byteLength; i++) {
        combinedView.setUint8(offset++, dataView[i]);
    }

    return combinedBuffer;
}

// 定义 parseBinaryDataToObject 函数
function parseBinaryDataToObject(event) {
    let combinedView = new DataView(event.data);
    console.log('[receive] total packet length:', combinedView.byteLength);
    // 读取字节数据
    let magic = combinedView.getUint8(0);
    let cmd = combinedView.getUint32(1);

    let version = combinedView.getUint8(5);

    let encrypt = combinedView.getUint8(6);

    let serial = combinedView.getUint8(7);

    let length = combinedView.getUint32(8);

    // 获取字符串数据的位置和长度
    let dataOffset = 12;

    let dataLength = combinedView.byteLength - dataOffset;

    // 创建一个只包含字符串部分的新ArrayBuffer
    let dataBuffer = event.data.slice(dataOffset, dataOffset + dataLength);

    // 解码为字符串
    let decoder = new TextDecoder();
    let dataStr = decoder.decode(dataBuffer);

    return {
        cmd,
        version,
        encrypt,
        serial,
        length,
        data: dataStr
    };
}

// 定义 uuid 函数
function uuid() {
    var s = [];
    var hexDigits = "0123456789abcdef";
    for (var i = 0; i < 36; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
    }
    s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
    s[8] = s[13] = s[18] = s[23] = "-";

    var uuid = s.join("");
    return uuid;
}

// 定义 heartBeat 函数
function heartBeat() {
    setTimeout(() => {
        console.log("ping...");
        var messageData = {
            // "sendId": ""
        };
        var jsonData = JSON.stringify(messageData);
        // console.log(jsonData)
        socket.send(createCustomMessage(2, 1, 1, 10, jsonData));
    }, 30000);
}
